package centrifuge

import (
	"encoding/json"
	"flag"
	"fmt"
	"github.com/simonvetter/modbus"
	"math"
	"time"
	"toyota-client1/app/socket"
	"toyota-client1/init/global"
	j_log "toyota-client1/init/j-log"
	"toyota-client1/model"
	"toyota-client1/utils/tools"
)

const NAME = "centrifuge"
const BASE_ADDR = uint16(2549)

var Client *modbus.ModbusClient

// Data 离心机原始点位数据
var Data *model.CentrifugeRaw

func Run() {
	defer func() {
		time.Sleep(3 * time.Second)
		Run()
	}()
	Data = &model.CentrifugeRaw{}
	addr := global.AppConfig.Section(NAME).Key("addr").String()
	protocol := global.AppConfig.Section(NAME).Key("protocol").String()
	portName := global.AppConfig.Section(NAME).Key("port_name").String()
	baudRate, _ := global.AppConfig.Section(NAME).Key("baud_rate").Int()
	dataBits, _ := global.AppConfig.Section(NAME).Key("data_bits").Int()
	stopBits, _ := global.AppConfig.Section(NAME).Key("stop_bits").Int()
	parityMode, _ := global.AppConfig.Section(NAME).Key("parity_mode").Int()
	scanRate, _ := global.AppConfig.Section(NAME).Key("scan_rate").Int()
	slaveID, _ := global.AppConfig.Section(NAME).Key("slave_id").Int()
	moduleID, _ := global.AppConfig.Section(NAME).Key("module_id").Int()

	flag.Parse()
	if addr == "" {
		j_log.LogError([]interface{}{fmt.Sprintf("【%s】 addr cant bt empty", NAME)})
		return
	}
	if protocol == "" {
		j_log.LogError([]interface{}{fmt.Sprintf("【%s】 protocol cant bt empty", NAME)})
		return
	}
	if scanRate <= 0 {
		scanRate = 1000
	}
	if protocol != "rtu" && protocol != "tcp" {
		j_log.LogError([]interface{}{fmt.Sprintf("【%s】 protocol must be one of RTU, TCP", NAME)})
		return
	}
	var err error
	url := ""
	if protocol == "rtu" {
		url = protocol + "://" + portName
		j_log.LogInfo([]interface{}{fmt.Sprintf("【%s】 is connecting to %s", NAME, url)})
		switch uint(parityMode) {
		case modbus.PARITY_NONE:
		case modbus.PARITY_EVEN:
		case modbus.PARITY_ODD:
		default:
			j_log.LogError([]interface{}{fmt.Sprintf("【%s】 modbus rtu奇偶校验只能是 [0,1,2]", NAME)})
			return
		}
		Client, err = modbus.NewClient(&modbus.ClientConfiguration{
			URL:      url,
			Speed:    uint(baudRate),   // default
			DataBits: uint(dataBits),   // default, optional
			Parity:   uint(parityMode), // default, optional
			StopBits: uint(stopBits),   // default if no parity, optional
			Timeout:  300 * time.Millisecond,
		})
	} else {
		url = protocol + "://" + addr
		j_log.LogInfo([]interface{}{fmt.Sprintf("【%s is connecting to %s", NAME, url)})
		Client, err = modbus.NewClient(&modbus.ClientConfiguration{
			URL:     url,
			Timeout: 1 * time.Second,
		})
	}
	if err != nil {
		j_log.LogError([]interface{}{fmt.Sprintf("【%s】 modbus.NewClient error ", NAME)})
		return
	}
	err = Client.Open()
	if err != nil {
		j_log.LogError([]interface{}{fmt.Sprintf("【%s】 client.Open error ", NAME)})
		return
	}
	defer Client.Close()
	j_log.LogInfo([]interface{}{fmt.Sprintf("【%s】%s", NAME, "modbus连接成功")})
	// 开始循环循环读
	for {
		err0 := Client.SetUnitId(uint8(slaveID))
		if err0 != nil {
			j_log.LogWarning([]interface{}{fmt.Sprintf("【%s】SetUnitId error ", NAME)})
			return
		}
		buffer, err2 := Client.ReadRegisters(BASE_ADDR, 50, modbus.HOLDING_REGISTER)
		if err2 != nil {
			j_log.LogWarning([]interface{}{fmt.Sprintf("【%s】ReadRegisters part1 %v", NAME, err2.Error())})
			return
		} else {
			Data.SlaveID = uint8(slaveID)
			Data.D2550 = buffer[0]
			Data.D2551 = buffer[1]
			Data.D2552 = buffer[2]
			Data.D2553 = buffer[3]
			Data.D2558 = buffer[8]
			Data.D2559 = buffer[9]
			Data.D2560 = buffer[10]
			Data.D2561 = buffer[11]
			Data.D2562 = buffer[12]
			Data.D2563 = buffer[13]
			Data.D2571 = buffer[21]
			Data.D2572 = buffer[22]
			Data.D2573 = buffer[23]
			Data.D2574 = buffer[24]
			Data.D2577 = RealValue(buffer[27], 1, false)
			Data.D2578 = RealValue(buffer[28], 1, false)
			D2580Bits := Uint16ToBinaryArray(buffer[30])
			Data.D25800 = uint8(D2580Bits[0])
			Data.D25801 = uint8(D2580Bits[1])
			Data.D25802 = uint8(D2580Bits[2])
			Data.D25803 = uint8(D2580Bits[3])
			Data.D25804 = uint8(D2580Bits[4])
			Data.D25805 = uint8(D2580Bits[5])
			Data.D25806 = uint8(D2580Bits[6])

			Data.D2581 = buffer[31]
			Data.D2582 = RealValue(buffer[32], 1, false)
			Data.D2583 = RealValue(buffer[33], 1, false)
			Data.D2584 = RealValue(buffer[34], 1, false)
			Data.D2585 = RealValue(buffer[35], 1, false)
			Data.D2586 = RealValue(buffer[36], 1, false)
			Data.D2587 = buffer[37]
			Data.D2588 = buffer[38]
			Data.D2589 = buffer[39]
			Data.D2590 = RealValue(buffer[40], 1, false)
			Data.D2591 = RealValue(buffer[41], 1, false)
			Data.D2595 = RealValue(buffer[45], 1, false)
			Data.D2596 = RealValue(buffer[46], 1, false)
			Data.D2597 = RealValue(buffer[47], 1, false)
			Data.D2598 = RealValue(buffer[48], 1, false)
			Data.D2599 = RealValue(buffer[49], 1, false)
		}
		buffer, err2 = Client.ReadRegisters(BASE_ADDR+50, 50, modbus.HOLDING_REGISTER)
		if err2 != nil {
			j_log.LogWarning([]interface{}{fmt.Sprintf("【%s】ReadRegisters part2 %v", NAME, err2.Error())})
			return
		} else {
			Data.D2600 = RealValue(buffer[0], 1, false)
			Data.D2601 = RealValue(buffer[1], 1, false)
			Data.D2602 = RealValue(buffer[2], 1, false)
			Data.D2603 = RealValue(buffer[3], 1, false)
			Data.D2604 = RealValue(buffer[4], 1, false)
			Data.D2605 = RealValue(buffer[5], 1, false)
			Data.D2606 = RealValue(buffer[6], 1, false)
			Data.D2607 = RealValue(buffer[7], 1, false)
			Data.D2608 = int16(buffer[8])
			Data.D2609 = int16(buffer[9])
			Data.D2610 = RealValue(buffer[10], 1, false)
			Data.D2611 = RealValue(buffer[11], 1, false)
			Data.D2612 = RealValue(buffer[12], 1, false)
			Data.D2620 = RealValue(buffer[20], 1, false)
			Data.D2621 = RealValue(buffer[21], 1, false)
			Data.D2622 = RealValue(buffer[22], 1, false)
			Data.D2623 = RealValue(buffer[23], 1, false)
			Data.D2624 = int16(buffer[24])
			Data.D2625 = int16(buffer[25])
			Data.D2627 = RealValue(buffer[27], 1, false)
			Data.D2628 = RealValue(buffer[28], 1, false)
			Data.D2629 = RealValue(buffer[29], 1, false)
			Data.D2630 = RealValue(buffer[30], 1, false)
			Data.D2631 = RealValue(buffer[31], 1, false)
			Data.D2632 = RealValue(buffer[32], 1, false)
			Data.D2633 = RealValue(buffer[33], 1, false)
			Data.D2635 = RealValue(buffer[35], 2, false)
			Data.D2636 = int16(buffer[36])
			Data.D2637 = RealValue(buffer[37], 1, false)
			Data.D2638 = int16(buffer[38])
			Data.D2639 = RealValue(buffer[39], 1, false)
			Data.D2640 = RealValue(buffer[40], 1, false)
			Data.D2641 = RealValue(buffer[41], 1, false)
			Data.D2642 = int16(buffer[42])
			Data.D2643 = RealValue(buffer[43], 1, false)
			Data.D2644 = RealValue(buffer[44], 1, false)
			Data.D2645 = RealValue(buffer[45], 1, false)
			Data.D2646 = RealValue(buffer[46], 1, false)
			Data.D2647 = RealValue(buffer[47], 1, false)
			Data.D2648 = RealValue(buffer[48], 1, false)
			Data.D2649 = RealValue(buffer[49], 1, false)
		}
		buffer, err2 = Client.ReadRegisters(BASE_ADDR+100, 45, modbus.HOLDING_REGISTER)
		if err2 != nil {
			j_log.LogWarning([]interface{}{fmt.Sprintf("【%s】ReadRegisters part3 %v", NAME, err2.Error())})
			return
		} else {
			Data.D2650 = RealValue(buffer[0], 1, false)
			Data.D2651 = int16(buffer[1])
			Data.D2652 = RealValue(buffer[2], 1, false)
			Data.D2660 = buffer[10]
			Data.D2661 = buffer[11]
			Data.D2662 = buffer[12]
			Data.D2663 = buffer[13]
			Data.D2664 = buffer[14]

			D2665Bits := Uint16ToBinaryArray(buffer[15])
			Data.D26650 = uint8(D2665Bits[0])
			Data.D26651 = uint8(D2665Bits[1])
			Data.D26652 = uint8(D2665Bits[2])
			Data.D26653 = uint8(D2665Bits[3])
			Data.D26654 = uint8(D2665Bits[4])

			D2666Bits := Uint16ToBinaryArray(buffer[16])
			Data.D26660 = uint8(D2666Bits[0])
			Data.D26661 = uint8(D2666Bits[1])
			Data.D26662 = uint8(D2666Bits[2])
			Data.D26663 = uint8(D2666Bits[3])
			Data.D26664 = uint8(D2666Bits[4])
			Data.D26665 = uint8(D2666Bits[5])
			Data.D26666 = uint8(D2666Bits[6])
			Data.D26667 = uint8(D2666Bits[7])
			Data.D26668 = uint8(D2666Bits[8])
			Data.D26669 = uint8(D2666Bits[9])
			Data.D266610 = uint8(D2666Bits[10])

			D2669Bits := Uint16ToBinaryArray(buffer[19])
			Data.D26690 = uint8(D2669Bits[0])
			Data.D26691 = uint8(D2669Bits[1])
			Data.D26692 = uint8(D2669Bits[2])
			Data.D26693 = uint8(D2669Bits[3])
			Data.D26694 = uint8(D2669Bits[4])
			Data.D26695 = uint8(D2669Bits[5])
			Data.D26696 = uint8(D2669Bits[6])
			Data.D26697 = uint8(D2669Bits[7])
			Data.D26698 = uint8(D2669Bits[8])
			Data.D26699 = uint8(D2669Bits[9])
			Data.D266910 = uint8(D2669Bits[10])
			Data.D266911 = uint8(D2669Bits[11])
			Data.D266912 = uint8(D2669Bits[12])
			Data.D266913 = uint8(D2669Bits[13])
			Data.D266914 = uint8(D2669Bits[14])
			Data.D266915 = uint8(D2669Bits[15])
			D2670Bits := Uint16ToBinaryArray(buffer[20])
			Data.D26700 = uint8(D2670Bits[0])
			Data.D26701 = uint8(D2670Bits[1])
			Data.D26702 = uint8(D2670Bits[2])
			Data.D26703 = uint8(D2670Bits[3])
			Data.D26704 = uint8(D2670Bits[4])
			Data.D26705 = uint8(D2670Bits[5])
			Data.D26706 = uint8(D2670Bits[6])
			Data.D26707 = uint8(D2670Bits[7])
			Data.D26708 = uint8(D2670Bits[8])
			Data.D26709 = uint8(D2670Bits[9])
			Data.D267010 = uint8(D2670Bits[10])
			Data.D267011 = uint8(D2670Bits[11])
			Data.D267012 = uint8(D2670Bits[12])
			Data.D267013 = uint8(D2670Bits[13])
			Data.D267014 = uint8(D2670Bits[14])

			D2671Bits := Uint16ToBinaryArray(buffer[21])
			Data.D26710 = uint8(D2671Bits[0])
			Data.D26711 = uint8(D2671Bits[1])
			Data.D26712 = uint8(D2671Bits[2])
			Data.D26713 = uint8(D2671Bits[3])
			Data.D26714 = uint8(D2671Bits[4])

			Data.D2673 = RealValue(buffer[23], 1, false)
			Data.D2674 = RealValue(buffer[24], 1, false)
			Data.D2678 = buffer[28]
			Data.D2679 = buffer[29]
			Data.D2680 = buffer[30]
			Data.D2681 = buffer[31]
			Data.D2682 = buffer[32]

			D2683Bits := Uint16ToBinaryArray(buffer[33])
			Data.D26830 = uint8(D2683Bits[0])
			Data.D26831 = uint8(D2683Bits[1])
			Data.D26832 = uint8(D2683Bits[2])
			Data.D26833 = uint8(D2683Bits[3])
			Data.D26834 = uint8(D2683Bits[4])
			Data.D26835 = uint8(D2683Bits[5])
			Data.D26836 = uint8(D2683Bits[6])
			Data.D26837 = uint8(D2683Bits[7])
			Data.D26838 = uint8(D2683Bits[8])
			Data.D26839 = uint8(D2683Bits[9])
			Data.D268310 = uint8(D2683Bits[10])
			Data.D268311 = uint8(D2683Bits[11])
			Data.D268312 = uint8(D2683Bits[12])
			Data.D268313 = uint8(D2683Bits[13])
			Data.D268314 = uint8(D2683Bits[14])
			Data.D268315 = uint8(D2683Bits[15])

			D2684Bits := Uint16ToBinaryArray(buffer[34])
			Data.D26840 = uint8(D2684Bits[0])
			Data.D26841 = uint8(D2684Bits[1])
			Data.D26842 = uint8(D2684Bits[2])
			Data.D26843 = uint8(D2684Bits[3])
			Data.D26844 = uint8(D2684Bits[4])

			D2685Bits := Uint16ToBinaryArray(buffer[35])
			Data.D26850 = uint8(D2685Bits[0])
			Data.D26851 = uint8(D2685Bits[1])
			Data.D26852 = uint8(D2685Bits[2])
			Data.D26853 = uint8(D2685Bits[3])
			Data.D26854 = uint8(D2685Bits[4])
			Data.D26855 = uint8(D2685Bits[5])
			Data.D26856 = uint8(D2685Bits[6])
			Data.D26857 = uint8(D2685Bits[7])
			Data.D26858 = uint8(D2685Bits[8])
			Data.D26859 = uint8(D2685Bits[9])
			Data.D268510 = uint8(D2685Bits[10])
			Data.D268511 = uint8(D2685Bits[11])
			Data.D268512 = uint8(D2685Bits[12])
			Data.D268513 = uint8(D2685Bits[13])
			Data.D268514 = uint8(D2685Bits[14])
			Data.D268515 = uint8(D2685Bits[15])

			D2686Bits := Uint16ToBinaryArray(buffer[36])
			Data.D26860 = uint8(D2686Bits[0])
			Data.D26861 = uint8(D2686Bits[1])
			Data.D26862 = uint8(D2686Bits[2])
			Data.D26863 = uint8(D2686Bits[3])
			Data.D26864 = uint8(D2686Bits[4])
			Data.D26865 = uint8(D2686Bits[5])
			Data.D26866 = uint8(D2686Bits[6])
			Data.D26867 = uint8(D2686Bits[7])
			Data.D26868 = uint8(D2686Bits[8])
			Data.D26869 = uint8(D2686Bits[9])
			Data.D268610 = uint8(D2686Bits[10])
			Data.D268611 = uint8(D2686Bits[11])
			Data.D268612 = uint8(D2686Bits[12])
			Data.D268613 = uint8(D2686Bits[13])
			Data.D268614 = uint8(D2686Bits[14])
			Data.D268615 = uint8(D2686Bits[15])

			D2687Bits := Uint16ToBinaryArray(buffer[37])
			Data.D26870 = uint8(D2687Bits[0])
			Data.D26871 = uint8(D2687Bits[1])
			Data.D26872 = uint8(D2687Bits[2])
			Data.D26873 = uint8(D2687Bits[3])
			Data.D26874 = uint8(D2687Bits[4])
			Data.D26875 = uint8(D2687Bits[5])
			Data.D26876 = uint8(D2687Bits[6])
			Data.D26877 = uint8(D2687Bits[7])
			Data.D26878 = uint8(D2687Bits[8])
			Data.D26879 = uint8(D2687Bits[9])

			Data.D2689 = buffer[39]
			Data.D2692 = RealValue(buffer[42], 1, true)
			Data.D2693 = RealValue(buffer[43], 1, true)
			Data.D2694 = buffer[44]
		}
		jsonB, _ := json.Marshal(Data)
		_ = socket.Client.SendMessage(moduleID, NAME, string(jsonB))
		time.Sleep(time.Duration(scanRate) * time.Millisecond)
	}
}

// Uint16ToBinaryArray 项目专用
func Uint16ToBinaryArray(b uint16) (res []int) {
	binaryString := ""
	for i := 15; i >= 0; i-- { // 从最高位到最低位
		if (b & (1 << i)) != 0 {
			binaryString += "1"
		} else {
			binaryString += "0"
		}
	}
	res = tools.BinaryStringToArray(binaryString)
	tools.SliceReverse(&res)
	return
}

// RealValue 给原始数据加上系数
func RealValue(rawData uint16, precious int, unsigned bool) (f float64) {
	f0 := float64(rawData)
	if unsigned == false {
		f0 = float64(int16(rawData))
	}
	plusV := math.Pow10(precious)
	//f = tools.RoundFloat(f0/plusV, precious)
	f = f0 / plusV
	return
}
